<?php
/*

*/

/**
 * @todo doc
 */
class Item
{
  private $idItem;
  private $nomItem;
  private $lienItem;
  private $iconeItem;
  private $dateAjoutItem;
  private $proprietaireItem;
  private $typeItem;
  private $metaItem;
  private $tagsItem;
  private $descItem;
  private $droitsItem;
  private $more;
  private $infoCompl;

  /**
   * Constructeur de Item
   * 
   * @param int $id id de l'item à construire ou 0 si c'est un nouvel item (dans ce cas il faut remplir les autres param)
   * @param string $nom nom de l'item
   * @param string $lien chemin vers l'item (fichier ou lien internet)
   * @param int $droits entier définissant les droits (0, 1 ou 2)
   * @param string $proprietaire login de proprietaire de l'item
   * @param int $droits droits sur l'item par rapport a l'utilisateur en cours
   * @param array $tags tableau des tags associés à l'item
   */  
  public function __construct($id, $nom=null, $lien=null, $proprietaire=null, $droits=null, $tags=array(), $desc=null)
    {
      $this->more = array();
      // construction selon les donnees SQL fournies
      if(is_array($id))
	{
	  $res = $id;
	  $sql = SQL::GetInstance();

	  $this->idItem           = (int)$res['idItem'];
	  $this->nomItem          = $res['nomItem'];
	  $this->lienItem         = $res['lienItem'];
	  $this->iconeItem        = $res['iconeItem'];
	  $this->dateAjoutItem    = $res['dateAjoutItem'];
	  $this->proprietaireItem = $res['proprietaireItem'];
	  $this->typeItem         = $res['typeItem'];
	  $this->metaItem         = $res['metaItem'];
	  $this->droitsItem       = $res['droits'];
	  $this->descItem         = $res['descItem'];
	  $this->infoCompl        = $this->getInfoCompl();
	  //$this->tagsItem         = $sql->getTagsItem($this->idItem);
	  $this->tagsItem         = $this->infoCompl[1];
	}
      // construction via une requete SQL selon l'id
      elseif($id > 0)
	{
	  $this->idItem = (int)$id;
	  $sql = SQL::GetInstance();
	  $res = $sql->getItem($this->idItem);

	  $this->nomItem          = $res['nomItem'];
	  $this->lienItem         = $res['lienItem'];
	  $this->iconeItem        = $res['iconeItem'];
	  $this->dateAjoutItem    = $res['dateAjoutItem'];
	  $this->proprietaireItem = $res['proprietaireItem'];
	  $this->typeItem         = $res['typeItem'];
	  $this->metaItem         = $res['metaItem'];
	  $this->droitsItem       = $res['droits'];	
	  $this->descItem         = $res['descItem'];
	  $this->tagsItem         = $res['tags'];
	}
      // construction "a la main" en passant les parametres
      else
	{
	  if(is_null($id))
	    {
	      throw new ListerException(35);
	    }

	  if(!$this->checkNom($nom))
	    {
	      throw new ListerException(24);
	    }
	  // passé en argument
	  $this->nomItem          = $nom;
	  $this->lienItem         = $lien;
	  $this->tagsItem         = $tags;
	  $this->proprietaireItem = $proprietaire;
	  $this->droitsItem       = $droits;
	  $this->descItem         = $desc;
	  // défini par défaut
	  $this->iconeItem        = null;
	  $this->dateAjoutItem    = date("Y-m-d H:i:s");
	  // a trouver
	  $this->typeItem         = $this->trouverType();
	  $this->metaItem         = $this->trouverMeta();
	}

      // Si l'utilisateur est le proprietaire on lui donne tous les droits sur l'item, sauf en cas d'ajout
      if(!is_null($id)) 
	$this->droitsItem = ($this->isProprietaire()) ? 2 : $this->droitsItem;

      $this->tagsItem   = (is_null($this->tagsItem)) ? array() : $this->tagsItem;

      attention((is_null($this->nomItem)          ||
		 is_null($this->lienItem)         ||
		 is_null($this->proprietaireItem) ||
		 is_null($this->droitsItem)),
		"L'item $this->idItem a ete construit avec des proprietes manquantes");    
      startPlugin('Item___construct',$this);
    }

  /**
   * Les getters
   */
  public function getDateAjoutItem()    {return $this->dateAjoutItem;}
  public function getDroitsItem()       {return $this->droitsItem;}
  public function getIconeItem()        {return $this->iconeItem;}
  public function getIdItem()           {return $this->idItem;}
  public function getLienItem()         {return $this->lienItem;}
  public function getMetaItem()         {return $this->metaItem;}  
  public function getHtmlMeta()         {return $this->parseMeta(true);}
  public function getNomItem()          {return $this->nomItem;}
  public function getProprietaireItem() {return $this->proprietaireItem;}
  public function getTagsItem()         {return $this->tagsItem;}
  public function getTypeItem()         {return $this->typeItem;}
  public function getType()             {return $this->typeItem;}
  public function getLien()             {return $this->lienItem;}
  public function getNom()              {return $this->nomItem;}
  public function getDroits()           {return $this->droitsItem;}
  public function getMore()    {return $this->more;}
  public function getDesc() {return $this->descItem;}

  public function setDesc($desc) {$this->descItem = $desc;}
  public function setMore($more)       {$this->more    = array_merge($this->more,$more);}
  public function setDateAjoutItem($dateAjoutItem) {$this->dateAjoutItem = $dateAjoutItem;}
  public function setDroitsItem($droitsItem)       {$this->droitsItem    = $droitsItem;}
  public function setIconeItem($iconeItem)         {$this->iconeItem     = $iconeItem;}
  public function setIdItem($idItem)     {$this->idItem   = $idItem;}
  public function setLienItem($lienItem) {$this->lienItem = $lienItem;}
  public function setMetaItem($metaItem) {$this->metaItem = $metaItem;}
  public function setNomItem($nomItem)   {$this->nomItem  = $nomItem;}
  public function setTagsItem($tagsItem) {$this->tagsItem = $tagsItem;}
  public function addTagsItem($tag)      {$this->tagsItem[] = $tag;}
  public function setTypeItem($typeItem) {$this->typeItem = $typeItem;}
  public function setProprietaireItem($proprietaireItem) {$this->proprietaireItem = $proprietaireItem;}
									
  /**
   * Est ce que l'utilisateur est le proprietaire
   *
   * @param string $login login de l'utilisateur a tester
   * @return bool $ok vrai si il l'est
   */
  public function isProprietaire($login=null)
    {
      if(is_null($login)) $login = $_SESSION['LOGIN'];
      return ($login == $this->proprietaireItem || (bool)$_SESSION['IS_ADMIN']);
    }

  /**
   * Fait l'apercu de l'item si possible
   *
   * @return bool $ok true si tout s'est bien passe
   */
  public function faireApercu()
    {
      if($this->iconeItem == 'err') 
	{
	  return false;
	}

      include_once 'php/apercu.php';
      global $CONF;
      $fichier = apercu($this->idItem, $CONF['apercu_x'], $CONF['apercu_y']);

      $sql = SQL::GetInstance();
      if(empty($fichier))
	{
	  $sql->iconeItem($this->idItem, false);
	  return false;
	}

      // Ajoute le chemin de l'apercu cree dans la base
      $this->iconeItem = $fichier;
      startPlugin('Item_faireApercu',$this);
      return $sql->iconeItem($this->idItem, $fichier);
    }

  /**
   * Calcule la somme md5 de l'item
   *
   * @return string $md5
   */
  public function md5()
    {
      return fast_md5_file($this->lienItem);//md5_file($this->lienItem);
    }

  private function getInfoCompl()
    {    $sql = SQL::GetInstance();
    if(!isset($this->infoCompl))
      {
	$this->infoCompl = $sql->getTagsItemAndUtilisateurDroitsItem($this->idItem);
      }
    return $this->infoCompl;
    }

  /**
   * Trouve le type de l'item selon le mime du fichier ou extention sinon
   *
   * @return int $type type trouvé
   */
  private function trouverType()
    {
      $mime = null;
      if(function_exists('mime_content_type') && eregi('^http://', $this->lienItem))
	$mime = mime_content_type($this->lienItem);
      $ext  = trouveExtention($this->lienItem);

      switch($ext)
	{
	case 'fav': 
	  return FAV; 
	case 'vcf': 
	  return CON; 
	}

      if(ereg('^audio', $mime)) return AUD;
      if(ereg('^video', $mime)) return VID;
      if(ereg('^image', $mime)) return IMG;
      //if(ereg('^text' , $mime)) return DOC;

      // mime speciaux
      if($mime == 'application/pdf'              ||
	 $mime == 'application/msword'           ||
	 $mime == 'application/postscript'       ||
	 $mime == 'application/rtf'              ||
	 ereg('^application/wordperfect', $mime) ||
	 ereg('excel$', $mime)                   ||
	 ereg('powerpoint$', $mime)              ||
	 ereg('\.opendocument\.', $mime)         ||
	 ereg('\.sun\.xml\.', $mime)               ) 
	return DOC;

      if($mime == 'application/ogg') 
	return AUD;

      if($mime == 'application/rar' ||
	 $mime == 'application/zip'   )
	return ARC;

      require 'php/extension_type.php';
      if(isset($leType)) return $leType;

      // defaut
      return AUT;
    }
  
  /**
   * Méthode qui trouve les metas données d'une image
   */
  private function metaImage()
    {
      $out = '';
      if($info = @getimagesize($this->lienItem))
	{
	  $out .= "\t<image>\n";
	  $out .= "\t\t<x>".$info[0]."</x>\n";
	  $out .= "\t\t<y>".$info[1]."</y>\n";
	  switch ($info[2])
	    {
	    case 1:  $type = 'gif';   break;
	    case 2:  $type = 'jpg';   break;
	    case 3:  $type = 'png';   break;
	    default: $type = 'autre'; break;
	    }
	  
	  $res = @read_exif_data($this->lienItem);
	  
	  $cherche = array('Make', 'Model', 'DateTime');
	  foreach($cherche as $c)
	    {
	      $$c = isset($res[$c]) ? $res[$c] : null;
	    }
	  
	  $out .= "\t\t<type>".$type."</type>\n";
	  $out .= "\t\t<exif>\n\t\t\t<date>";
	  $out .= $DateTime;
	  $out .= "</date>\n\t\t\t<info>";
	  $out .= $Make.", ";
	  $out .= $Model."";
	  $out .= "</info>\n\t\t</exif>\n";
	  $out .= "\t</image>\n";
	  
	  return $out;
	}
    }
  
  /**
   * Méthode qui trouve les metas données d'un contact
   */
  private function metaContact()
    {
      $out = '';
      $out .= "\t<contact>\n";
      $card = new Contact_Vcard_Parse();
      $data = $card->fromFile($this->lienItem);
      if (isset($data[0]))
	{
	  $data = $data[0];
	  // Les informations d'identité
	  if (array_key_exists('N', $data) && isset($data['N'][0]))
	    {
	      $nom      = $data['N'][0]['value'][0][0];
	      $prenom   = $data['N'][0]['value'][1][0];
	      $civilite = $data['N'][0]['value'][3][0];
	    }
	  else
	    $civilite = $nom = $prenom = '';
	  
	  $out .= "\t\t".'<civilite>'.$civilite.'</civilite>'."\n";
	  $out .= "\t\t".'<prenom>'.$prenom.'</prenom>'."\n";
	  $out .= "\t\t".'<nom>'.$nom.'</nom>'."\n";
	  
	  // La date de naissance
	  if (array_key_exists('BDAY', $data) && isset($data['BDAY'][0]))
	    {
	      $bday = $data['BDAY'][0]['value'][0][0];
	    }
	  else
	    $bday = '';
	  
	  $out .= "\t\t".'<bday>'.$bday.'</bday>'."\n";
	  
	  // Les adresses mail
	  $out .= "\t\t".'<emails>'."\n";
	  if (array_key_exists('EMAIL', $data))
	    {
	      foreach ($data['EMAIL'] as $mail)
		{
		  $out .= "\t\t\t".'<'.strtolower(implode('_', $mail['param']['TYPE'])).'>'.$mail['value'][0][0].'</'.strtolower(implode('_', $mail['param']['TYPE'])).'>'."\n";
		}
	    }
	  $out .= "\t\t".'</emails>'."\n";
	  
	  // Les téléphones
	  $out .= "\t\t".'<phones>'."\n";
	  if (array_key_exists('TEL', $data))
	    {
	      foreach ($data['TEL'] as $tel)
		{
		  $out .= "\t\t\t".'<'.strtolower(implode('_', $tel['param']['TYPE'])).'>'.$tel['value'][0][0].'</'.strtolower(implode('_', $tel['param']['TYPE'])).'>'."\n";
		}
	    }
	  $out .= "\t\t".'</phones>'."\n";
	  
	  $out .= "\t\t".'<ims>'."\n";
	  $array_im = array('AIM', 'JABBER', 'YAHOO', 'MSN', 'ICQ');
	  foreach ($array_im as $im)
	    {
	      if (array_key_exists('X-'.$im, $data))
		{
		  $out .= "\t\t\t".'<'.strtolower($im).'>'.$data['X-'.$im][0]['value'][0][0].'</'.strtolower($im).'>'."\n";
		}
	    }
	  $out .= "\t\t".'</ims>'."\n";
	  
	  // Les adresses
	  $out .= "\t\t".'<addresses>'."\n";
	  if (array_key_exists('ADR', $data))
	    {
	      foreach ($data['ADR'] as $adr)
		{
		  $out .= "\t\t\t".'<'.strtolower(implode('_', $adr['param']['TYPE'])).'>'."\n";
		  $out .= "\t\t\t\t".'<rue>'.$adr['value'][2][0].'</rue>'."\n";
		  $out .= "\t\t\t\t".'<cp>'.$adr['value'][5][0].'</cp>'."\n";
		  $out .= "\t\t\t\t".'<ville>'.$adr['value'][3][0].'</ville>'."\n";
		  $out .= "\t\t\t\t".'<pays>'.$adr['value'][6][0].'</pays>'."\n";
		  $out .= "\t\t\t".'</'.strtolower(implode('_', $adr['param']['TYPE'])).'>'."\n";
		}
	    }
	  $out .= "\t\t".'</addresses>'."\n";
	  
	  // La photo !! happy feature :p On est des ouf ou on l'est pas :D
	  // Je ne te le fais pas dire ;)
	  if (array_key_exists('PHOTO', $data) && isset($data['PHOTO'][0]))
	    {
	      include_once 'php/apercu.php';
	      $this->iconeItem = apercu_vcard($data['PHOTO'][0]['value'][0][0]);
	    }
	  $out .= "\t\t".'<photo>'.$this->iconeItem.'</photo>'."\n";
	}
      $out .= "\t</contact>\n";
      return $out;
    }

  /**
   * Méthode qui trouve les métas d'un favoris
   */
  private function metaFavoris()
    {
      $out = '';
      $xml = @simplexml_load_file($this->lienItem);
      if ($xml)
	{
	  $out = file_get_contents($this->lienItem);
	  if ($ico = getFavicon($xml->url))
	    {
	      include_once 'php/apercu.php';
	      $this->iconeItem = apercu_favoris($ico);
	    }
	}
      return $out;
    }

  /**
   * Trouve les méta données de l'item.
   * Utilise différentes fonctions intégrées à php
   *
   * @return string $meta chaine XML des meta données
   * @see ./doc/structureMeta.xml
   */
  private function trouverMeta()
    {
      $this->out = '';
      
      $arrayFunctions = array(
			      IMG => 'metaImage',
			      CON => 'metaContact',
			      FAV => 'metaFavoris');

      if (array_key_exists($this->typeItem, $arrayFunctions))
	$this->out .= self::$arrayFunctions[$this->typeItem]();
      
      startPlugin('Item_trouverMeta',$this);
      return "<meta>\n".$this->out."</meta>\n";
    }
  
  /**
   * Méthode qui enregistre l'item en base
   */
  public function enregistrer()
    {
      $sql = SQL::GetInstance();
      
      if(! $sql->enregistrerItem($this->nomItem, $this->lienItem, $this->iconeItem, $this->proprietaireItem, $this->typeItem, $this->descItem, $this->metaItem, $id))
	{  
	  throw new ListerException(1, $this->nomItem);
	}
      
      $this->idItem = $id;
      
      $this->changerDroits($this->droitsItem, $this->proprietaireItem);
      
      foreach($this->tagsItem as $tag)
	{
	  $this->ajouterTag($tag);
	}
      
      global $CONF;
      if($CONF['ap_sync'])
	{
	  $this->faireApercu();
	}
      startPlugin('Item_enregistrer',$this);
    }

/**
 * Méthode qui supprime l'item en base
 */
public function supprimer()
{
  $sql = SQL::GetInstance();
  startPlugin('Item_supprimer',$this);
  if(! $sql->supprimerItem($this->idItem))
    {
      throw new ListerException(2, $this->nomItem);
    }
}

/**
 * Méthode qui change le nom de l'item en base et dans l'objet courant
 *
 * @param string $nouvNom Nouveau nom de l'item
 */  
public function renommer($nouvNom=null)
{
  $n = is_null($nouvNom) ? $this->nomItem : $nouvNom;
  if(!$this->checkNom($n))
    {
      throw new ListerException(24);
    }
   
  $sql = SQL::GetInstance();
  if(! $sql->renommerItem($this->idItem, $n))
    {
      throw new ListerException(3, $this->nomItem);
    }
    
  $this->nomItem = $n;
  startPlugin('Item_renommer',$this);
}
  
/**
 * Méthode qui enregistre la desc de l'item en base
 *
 * @param string $nvelleDesc nouvelle description
 */  
public function enregistrerDesc($nvelleDesc=null)
{
  $d = is_null($nvelleDesc) ? $this->descItem : $nvelleDesc;
  $sql = SQL::GetInstance();
  if(! $sql->changerDescItem($this->idItem, $d))
    {
      throw new ListerException(301, $this->nomItem);
    }
    
  $this->descItem = $d;
  startPlugin('Item_enregistrerDesc',$this);
}  
  
/**
 * Methode qui ajoute un tag a un item
 *
 * @param string $tag nom du tag a ajouter
 */
public function ajouterTag($tag)
{
  $sql = SQL::GetInstance();
  if(! $sql->ajouterTagItem($tag, $this->idItem))
    {
      throw new ListerException(17, $tag);
    }

  // On l'ajoute a l'item instancie
  $this->tagsItem[] = $tag;
  startPlugin('Item_ajouterTag',$this);
}

/**
 * Methode qui supprimer un tag a un item
 *
 * @param string $tag nom du tag a supprimer
 */
public function retirerTag($tag)
{
  $sql = SQL::GetInstance();
  if(! $sql->supprimerTagItem($tag, $this->idItem))
    {
      throw new ListerException(18, $tag);
    }

  // On enleve le tag de l'item instancie
  unset($this->tagsItem[array_search($tag, $this->tagsItem)]);
  startPlugin('Item_retirerTag',$this);
}

/**
 * Methode qui change l'etat d'un tag sur un item.
 * Ajoute le tag si il n'est pas deja sur l'item, le supprime sinon
 *
 * @param string $tag nom du tag
 */
public function invTag($tag)
{
  if(in_array($tag, $this->tagsItem))
    {
      $this->retirerTag($tag);
    }
  else
    {
      $this->ajouterTag($tag);
    }
}

/**
 * Fait la liste des utilisateurs avec les droits de lecture/ecriture sur l'item courant.
 * Sert pour remplir le template.
 *
 * @return array $listeUser tableau des logins
 */
public function listeUtilisateurDroits()
{
  $sql = SQL::GetInstance();
  $users = $sql->getUtilisateurs('all');
  $t = $this->getInfoCompl();
  $t = $t[0];
  $l = array();
  $i = $j = $k = $g = 0;
  if(!empty($t)) 
    {
      foreach($t as $unRes)
	{
	  if(!in_array($unRes['login'],$l))
	    {
	      if($unRes['droits'] == 1)
		{
		  $res['utilisateurLecture.'][$i++]['LOGIN'] = $unRes['login'];
		}
	      elseif($unRes['droits'] == 2)
		{
		  $res['utilisateurModification.'][$j++]['LOGIN'] = $unRes['login'];
		}
	      else
		{
		  $res['utilisateurNone.'][$k++]['LOGIN'] = $unRes['login'];
		}
	      $l[] = $unRes['login'];
	    }
	}
    }
  
  foreach($users as $u)
    {
      if(!in_array($u,$l))
	{
	  $res['utilisateurNone.'][$k++]['LOGIN'] = $u;
	}
    }
  return $res;
}

/**
 * Change les droits sur l'item pour un utilisateur donnée
 *
 * @param int $droits les droits donnés (1 = lecture, 2 = tous les droits)
 * @param string $login le login de l'utilisateur a qui ont applique les droits
 * @return bool $ok true si tout s'est bien passé
 */
public function changerDroits($droits, $login)
{
  $sql = SQL::GetInstance();
  startPlugin('Item_changerDroits',$this);
  return $sql->changerDroitsItem($this->idItem, $login, $droits);

}

/**
 * Rend l'item public càd que tout le monde peut le voir mais pas le modifier,
 * ou le rend privé càd que les visiteurs ne le verrons plus mais les autres droits restent
 *
 * @param bool $etat true rend public, false privé
 * @return bool $ok true si tout s'est bien passé
 */
public function changerPublic($etat)
{
  $sql = SQL::GetInstance();
  startPlugin('Item_changerPublic',$this);
  return $sql->changerPublicItem($this->idItem, $etat);
}


/**
 * Méthode qui retourne un tableau contenant les infos de l'item, pour le template
 *
 * @return array $t Tableau contenant les infos de l'item
 */
public function returnArray()
{
  $d = trDate($this->dateAjoutItem);
  global $CONF;
  $iconeItem = (is_null($this->iconeItem) || empty($this->iconeItem) || !file_exists($this->iconeItem)) 
    ? $CONF['theme_dir'].'/icone/'.$this->typeItem.'.png' : $this->iconeItem;


  startPlugin('Item_returnArray',$this);
  return array_merge($this->parseMeta(), $this->listeUtilisateurDroits(), array(
	   'ID_ITEM'           => $this->idItem,
	   'NOM_ITEM'          => $this->nomItem,
	   'LIEN_ITEM'         => $this->lienItem,
	   'DATE_AJOUT_ITEM'   => $this->dateAjoutItem,
	   'DATE_Y'            => $d['y'],
	   'DATE_M'            => $d['m'],
	   'DATE_D'            => $d['d'],
	   'DATE_H'            => $d['h'],
	   'DATE_N'            => $d['n'],
	   'DATE_S'            => $d['s'],
	   'PROPRIETAIRE_ITEM' => $this->proprietaireItem,
	   'DROITS_ITEM'       => $this->droitsItem,
	   'TYPE_ITEM'         => $this->typeItem,
	   'TAGS_ITEM'         => implode(", ", $this->tagsItem),
	   'ICONE_ITEM'        => $iconeItem,
	   'META_ITEM'         => $this->metaItem,
	   'DESC_ITEM'         => $this->descItem,
	   'META_ITEM_HTML'    => $this->parseMeta(true)),$this->more);
}

/**
 * Méthode qui vérifit que le nom est valide
 *
 * @param string nom le nom a vérifier
 * @return bool ok vrai si pas de probleme
 */
private function checkNom($n)
{
  return !ereg('(\+|")', $n);
}


/**
 * Parse les meta données XML de l'item
 *
 * @return array $t tableau des meta données trouvées
 */
private function parseMeta($html=false)
{
  //--- faire un truc qui remplis automatiquement le template avec des clefs issues de la structure XML
  if(!ereg('^<meta>', $this->metaItem))
    {
      attention(true, "Les metas donnees de '$this->idItem'  ne sont pas valides");
      return array();
    }

  $xml = @simplexml_load_string($this->metaItem); // en cas d'erreur d'encoding !
  $res = array();

  include('xml2array.php');

  if($html)
    {
      $_HTML = '';
      foreach($res as $clef => $val)
	{
	  $_HTML .= '<span class="meta meta_'.$clef.'">'.$val.'</span>'."\n";
	}
      return $_HTML;
    }

  return $res;
}
}

?>
